package com.example.administrator.bleapp;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.listener.OnItemClickListener;
import com.example.administrator.bleapp.adapter.DeviceListAdapter;
import com.vise.baseble.ViseBle;
import com.vise.baseble.callback.scan.IScanCallback;
import com.vise.baseble.callback.scan.ScanCallback;
import com.vise.baseble.model.BluetoothLeDevice;
import com.vise.baseble.model.BluetoothLeDeviceStore;

import org.reactivestreams.Subscription;

import java.util.List;

import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
import io.reactivex.FlowableEmitter;
import io.reactivex.FlowableOnSubscribe;
import io.reactivex.functions.Action;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;

public class DeviceListActivity extends AppCompatActivity {

    RecyclerView recyclerView;
    private DeviceListAdapter deviceListAdapter;

    BluetoothLeDeviceStore bluetoothLeDeviceStore = new BluetoothLeDeviceStore();
    private ScanCallback scanCallback;

    public static void start(Activity context) {
        Intent starter = new Intent(context, DeviceListActivity.class);
        context.startActivity(starter);
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_device_list);
        initView();
        initData();
    }

    /**
     * 停止扫描
     */
    private void stopScan() {
        if (scanCallback != null) {
            ViseBle.getInstance().stopScan(scanCallback);
            invalidateOptionsMenu();
        }
    }

    private static final String TAG = "DeviceListActivity";
    private void initData() {

        Flowable.create(new FlowableOnSubscribe<BluetoothLeDevice>() {
            @Override
            public void subscribe(final FlowableEmitter<BluetoothLeDevice> e) throws Exception {
                scanCallback = new ScanCallback(new IScanCallback() {
                    @Override
                    public void onDeviceFound(BluetoothLeDevice bluetoothLeDeviceStore) {
                        e.onNext(bluetoothLeDeviceStore);
                    }

                    @Override
                    public void onScanFinish(BluetoothLeDeviceStore bluetoothLeDeviceStore) {
                        e.onComplete();
                    }

                    @Override
                    public void onScanTimeout() {
                        e.onError(new Throwable("超時"));
                    }
                });
                ViseBle.getInstance().startScan(scanCallback);
            }
        }, BackpressureStrategy.BUFFER)
                .map(new Function<BluetoothLeDevice, List<BluetoothLeDevice>>() {
                    @Override
                    public List<BluetoothLeDevice> apply(BluetoothLeDevice bluetoothLeDevice) throws Exception {
                        bluetoothLeDeviceStore.addDevice(bluetoothLeDevice);
                        return bluetoothLeDeviceStore.getDeviceList();
                    }
                })
                .doOnSubscribe(new Consumer<Subscription>() {
                    @Override
                    public void accept(Subscription subscription) throws Exception {
                        invalidateOptionsMenu();
                    }
                })
                .doOnTerminate(new Action() {
                    @Override
                    public void run() throws Exception {
                        invalidateOptionsMenu();
                    }
                })
                .subscribe(new Consumer<List<BluetoothLeDevice>>() {
                    @Override
                    public void accept(List<BluetoothLeDevice> bluetoothLeDevice) throws Exception {
                        deviceListAdapter.setNewData(bluetoothLeDevice);
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        Log.e(TAG, "accept: ",throwable );
                    }
                });

    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.menu_scan:
                initData();
                break;
            case R.id.menu_stop:
                stopScan();
                break;
        }
        return true;
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.scan,menu);
        if (scanCallback != null && !scanCallback.isScanning()) {
            menu.findItem(R.id.menu_stop).setVisible(false);
            menu.findItem(R.id.menu_scan).setVisible(true);
            menu.findItem(R.id.menu_refresh).setActionView(null);
        } else {
            menu.findItem(R.id.menu_stop).setVisible(true);
            menu.findItem(R.id.menu_scan).setVisible(false);
            menu.findItem(R.id.menu_refresh).setActionView(R.layout.actionbar_progress_indeterminate);
        }
        return true;

    }

    private void initView() {

        recyclerView = findViewById(R.id.recycle);

        deviceListAdapter = new DeviceListAdapter(null);

        recyclerView.setLayoutManager(new LinearLayoutManager(getBaseContext()));
        recyclerView.setAdapter(deviceListAdapter);

        recyclerView.addOnItemTouchListener(new OnItemClickListener() {
            @Override
            public void onSimpleItemClick(BaseQuickAdapter adapter, View view, int position) {
                BluetoothLeDevice item = deviceListAdapter.getItem(position);
                DeviceControlActivity.start(DeviceListActivity.this,item);
                stopScan();
            }
        });
    }
}
